package com.market.plus.core.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.TableGenerator;

@Entity
@Table(name = "Relationship")
@NamedQueries( { 
   @NamedQuery(name = Relationship.FIND_BY_NAME, query = "SELECT relation FROM Relationship relation where LOWER(relation.relationName)=LOWER(:name) and relation.participant.id=:id")})
public class Relationship implements Persistable, ModifyedInfo{

   public static final String FIND_BY_NAME = "RELATIONSHIP.FIND_BY_NAME";

   public static final String PARA_ID = "id";

   public static final String PARA_NAME = "name";

   @Id
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "GEN_RELATIONSHIP")
   @TableGenerator(name = "GEN_RELATIONSHIP", table = "SEQUENCE_LIST", allocationSize = 1, initialValue = 1, pkColumnName = "NAME", valueColumnName = "NEXT_SEQUENCE", pkColumnValue = "RELATIONSHIP")
   @Column(name = "RELATIONSHIP_ID")
   private Long id;

   @Column(name="Relation_Name")
   private String relationName;

   @ManyToMany
   @JoinTable(name = "RELATIONSHIP_FRIEND", joinColumns = @JoinColumn(name = "RELATIONSHIP_ID", referencedColumnName = "RELATIONSHIP_ID"), 
         inverseJoinColumns = @JoinColumn(name = "FRIEND_ID", referencedColumnName = "FRIEND_ID"))
   private Set<Friend> friends;

   @ManyToOne
   @JoinColumn(name="Participant_Id")
   private Participant participant;

   @Column(name = "CREATED_USER")
   private String createdUser;

   @Column(name = "CREATED_DATE")
   private Date createdDate;

   @Column(name = "MODIFYED_USER")
   private String modifyedUser;

   @Column(name = "MODIFYED_DATE")
   private Date modifyedDate;

   @Column(name="HasPrivated")
   private Boolean hasPrivated;

   @Enumerated
   @Column(name="LockStatus")
   private LockStatus lockStatus;

   public Relationship() {
      this.friends = new HashSet<Friend>();
   }

   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }


   public String getCreatedUser() {
      return createdUser;
   }

   public void setCreatedUser(String createdUser) {
      this.createdUser = createdUser;
   }

   public Date getCreatedDate() {
      return createdDate;
   }

   public void setCreatedDate(Date createdDate) {
      this.createdDate = createdDate;
   }

   public String getModifyedUser() {
      return modifyedUser;
   }

   public void setModifyedUser(String modifyedUser) {
      this.modifyedUser = modifyedUser;
   }

   public Date getModifyedDate() {
      return modifyedDate;
   }

   public void setModifyedDate(Date modifyedDate) {
      this.modifyedDate = modifyedDate;
   }

   public String getRelationName() {
      return relationName;
   }

   public void setRelationName(String relationName) {
      this.relationName = relationName;
   }

   public Participant getParticipant() {
      return participant;
   }

   public void setParticipant(Participant participant) {
      this.participant = participant;
   }

   public List<Friend> getFriends() {
      List<Friend> friends = new ArrayList<Friend>(this.friends);
      return friends;
   }

   public void setFriends(List<Friend> friends) {
      this.friends.clear();
      this.friends.addAll(friends);
   }
   
   public void addFriend(Friend friend){
      this.friends.add(friend);
   }

   public void removeFriend(Friend friend){
      this.friends.remove(friend);
   }

   public LockStatus getLockStatus() {
      return lockStatus;
   }

   public void setLockStatus(LockStatus lockStatus) {
      this.lockStatus = lockStatus;
   }

   public Boolean getHasPrivated() {
      return hasPrivated;
   }

   public void setHasPrivated(Boolean hasPrivated) {
      this.hasPrivated = hasPrivated;
   }
}

